﻿// <copyright file="OpacitySlider.cs" company="Oleg V. Polikarpotchkin">
// Copyright © 2009 Oleg V. Polikarpotchkin. All Right Reserved
// </copyright>
// <author>Oleg V. Polikarpotchkin</author>
// <email>ov-p@yandex.ru</email>
// <date>2009-06-05</date>
// <summary>OpenWPFChart library.
// ColorPickerControls. OpacitySlider provides for the Opacity selection.</summary>
// <revision>$Id$</revision>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace OpenWPFChart.Helpers.ChooseColorDialog
{
	/// <summary>
	/// Provides for the Opacity selection.
	/// </summary>
	public class OpacitySlider : Slider
	{
		/// <summary>
		/// Initializes the <see cref="OpacitySlider"/> class.
		/// </summary>
		static OpacitySlider()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(OpacitySlider)
				, new FrameworkPropertyMetadata(typeof(OpacitySlider)));
		}

		/// <summary>
		/// Updates the current position of the <see cref="T:System.Windows.Controls.Slider"/> 
		/// when the <see cref="P:System.Windows.Controls.Primitives.RangeBase.Value"/> 
		/// property changes.
		/// </summary>
		/// <param name="oldValue">The old 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Value"/> of the 
		/// <see cref="T:System.Windows.Controls.Slider"/>.</param>
		/// <param name="newValue">The new 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Value"/> of the 
		/// <see cref="T:System.Windows.Controls.Slider"/>.</param>
		protected override void OnValueChanged(double oldValue, double newValue)
		{
			base.OnValueChanged(oldValue, newValue);
			UpdateOpacity();
		}
		/// <summary>
		/// Responds to a change in the value of the 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Maximum"/> property.
		/// </summary>
		/// <param name="oldMaximum">The old value of the 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Maximum"/> property.</param>
		/// <param name="newMaximum">The new value of the 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Maximum"/> property.</param>
		protected override void OnMaximumChanged(double oldMaximum, double newMaximum)
		{
			base.OnMaximumChanged(oldMaximum, newMaximum);
			UpdateOpacity();
		}
		/// <summary>
		/// Responds to a change in the value of the 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Minimum"/> property.
		/// </summary>
		/// <param name="oldMinimum">The old value of the 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Minimum"/> property.</param>
		/// <param name="newMinimum">The new value of the 
		/// <see cref="P:System.Windows.Controls.Primitives.RangeBase.Minimum"/> property.</param>
		protected override void OnMinimumChanged(double oldMinimum, double newMinimum)
		{
			base.OnMinimumChanged(oldMinimum, newMinimum);
			UpdateOpacity();
		}

		/// <summary>
		/// Updates the SelectedOpacity property according to the Slider values.
		/// </summary>
		/// <remarks>
		/// Coerces the Slider Value to the SelectedOpacity property.
		/// </remarks>
		void UpdateOpacity()
		{
			SelectedOpacity = 1.0 - (Value - Minimum) / (Maximum - Minimum);
		}

		#region SelectedOpacity
		/// <summary>
		/// Backing SelectedOpacity property DependencyProperty.
		/// </summary>
		public static readonly DependencyProperty SelectedOpacityProperty
			= DependencyProperty.Register("SelectedOpacity", typeof(double), typeof(OpacitySlider),
				new FrameworkPropertyMetadata(1.0
					, FrameworkPropertyMetadataOptions.AffectsRender 
						| FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
					, SelectedOpacityChanged)
				, SelectedOpacityValidate);
		/// <summary>
		/// Gets or sets the SelectedOpacity.
		/// </summary>
		/// <value>The Opacity selected.</value>
		public double SelectedOpacity
		{
			get { return (double)GetValue(SelectedOpacityProperty); }
			set { SetValue(SelectedOpacityProperty, value); }
		}
		/// <summary>
		/// Validates the suggested Opacity value.
		/// </summary>
		/// <param name="value">Opacity value.</param>
		/// <returns></returns>
		static bool SelectedOpacityValidate(object value)
		{
			double opacity = (double)value;
			return (opacity >= 0.0 && opacity <= 1.0) ? true : false;
		}
		/// <summary>
		/// SelectedOpacity Property Changed event handler.
		/// </summary>
		/// <param name="d">The sender.</param>
		/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> 
		/// instance containing the event data.</param>
		static void SelectedOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			OpacitySlider ths = d as OpacitySlider;
			if (ths != null)
				ths.Value = (1.0 - ths.SelectedOpacity) * (ths.Maximum - ths.Minimum) + ths.Minimum;
		}
		#endregion SelectedOpacity
	}
}
